﻿using System;
using System;
using System.Web.UI.WebControls;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Xml;
using System.Collections;
using Rainy.DataAccess;

namespace Rainy.FrameWork
{
    /// <summary>
    /// key为不区分大小写的键值对
    /// </summary>
    public class FieldData : Hashtable
    {
        public FieldData()
            : base(System.StringComparer.Create(System.Globalization.CultureInfo.CurrentCulture, true))
        {
        }
        public FieldData(int capacity)
            : base(capacity, System.StringComparer.Create(System.Globalization.CultureInfo.CurrentCulture, true))
        {

        }
    }
    /// <summary>
    /// 基本数据操作类
    /// </summary>
    public class DataOperation
    {
        /// <summary>
        /// 数据库访问层
        /// </summary>
        public DBDataAccess db;

        private string message = "未定义错误信息";
        /// <summary>
        /// 用于保存缓存数据有效性判断的列名
        /// </summary>
        private const string bColumnName = "DataState";

        public DataOperation()
        {
            db = new DBDataAccess();
        }

        public DataOperation(string instance)
        {
            db = new DBDataAccess(instance);
        }

        /// <summary>
        /// 得到一行数据
        /// </summary>
        /// <param name="strSql"></param>
        /// <returns></returns>
        public DataRow GetRow(string strSql)
        {
            DataRow drow = null;
            try
            {
                DataSet dst = db.ExecuteParamDataSet(strSql, new string[] { });
                if (dst != null && dst.Tables.Count > 0 && dst.Tables[0].Rows.Count != 0)
                {
                    drow = dst.Tables[0].Rows[0];
                }
            }
            catch (Exception ex)
            {
                this.message = ex.Message;
            }
            return drow;
        }
        /// <summary>
        /// 获取某表中的单条记录
        /// </summary>
        /// <param name="table"></param>
        /// <param name="keyName"></param>
        /// <param name="keyValue"></param>
        /// <returns></returns>
        public DataRow GetRow(TableInfo mTableName, string keyValue)
        {
            string strSql = string.Format("select * from {0} where {1}=@{1} ", mTableName.TableName, mTableName.PrimaryName);

            object[] values = { keyValue };

            DataRow drow = null;
            try
            {
                DataSet dst = db.ExecuteParamDataSet(strSql, values);
                if (dst != null && dst.Tables.Count > 0 && dst.Tables[0].Rows.Count != 0)
                {
                    drow = dst.Tables[0].Rows[0];
                }
            }
            catch (Exception ex)
            {
                this.message = ex.Message;
            }
            return drow;
        }
        /// <summary>
        /// 获取某表中的单条记录
        /// </summary>
        /// <param name="table"></param>
        /// <param name="keyName"></param>
        /// <param name="keyValue"></param>
        /// <returns></returns>
        public DataRow GetRow(TableInfo mTableName, string strWhere, params object[] values)
        {
            string strSql = string.Format("select * from {0} where {1} ", mTableName.TableName, string.IsNullOrEmpty(strWhere) ? "1=1" : strWhere);

            DataRow drow = null;
            try
            {
                DataSet dst = db.ExecuteParamDataSet(strSql, values);
                if (dst != null && dst.Tables.Count > 0 && dst.Tables[0].Rows.Count != 0)
                {
                    drow = dst.Tables[0].Rows[0];
                }
            }
            catch (Exception ex)
            {
                this.message = ex.Message;
            }
            return drow;
        }
        /// <summary>
        /// 获取某表中所有记录
        /// </summary>
        /// <param name="table"></param>
        /// <param name="keyName"></param>
        /// <param name="keyValue"></param>
        /// <returns></returns>
        public DataSet GetDataSet(TableInfo eTableName)
        {
            return GetDataSet(eTableName, "*");
        }
        /// <summary>
        /// 获取某表中所有记录
        /// </summary>
        /// <param name="strSql"></param>
        /// <returns></returns>
        public DataSet GetDataSet(string strSql)
        {
            DataSet dst = null;
            try
            {
                dst = db.ExecuteDataSet(strSql);
            }
            catch (Exception ex)
            {
                this.message = ex.Message;
            }
            return dst;
        }
        /// <summary>
        /// 获取某表中所有记录
        /// </summary>
        /// <param name="table"></param>
        /// <param name="keyName"></param>
        /// <param name="keyValue"></param>
        /// <returns></returns>
        public DataSet GetDataSet(TableInfo eTableName, string showField)
        {
            DataSet dst = null;

            string strSql = string.Format("select {1} from {0} ", eTableName.TableName, showField);

            try
            {
                dst = db.ExecuteDataSet(strSql);
            }
            catch (Exception ex)
            {
                this.message = ex.Message;
            }
            return dst;
        }
        /// <summary>
        /// 获取某表中记录
        /// </summary>
        /// <param name="table"></param>
        /// <param name="keyName"></param>
        /// <param name="keyValue"></param>
        /// <returns></returns>
        public DataSet GetDataSet(TableInfo eTableName, string strWhere, params object[] values)
        {
            DataSet dst = null;

            string strSql = string.Format("select * from {0} where {1}", eTableName.TableName, string.IsNullOrEmpty(strWhere) ? "1=1" : strWhere);

            try
            {
                dst = db.ExecuteParamDataSet(strSql, values);
            }
            catch (Exception ex)
            {
                this.message = ex.Message;
            }
            return dst;
        }
        /// <summary>
        /// 获取某表中记录
        /// </summary>
        /// <param name="table"></param>
        /// <param name="keyName"></param>
        /// <param name="keyValue"></param>
        /// <returns></returns>
        public DataSet GetDataSetList(TableInfo eTableName, string showFields, string strWhere, params object[] values)
        {
            DataSet dst = null;

            string strSql = string.Format("select {1} from {0} where {2}", eTableName.TableName, string.IsNullOrEmpty(showFields) ? "*" : showFields, string.IsNullOrEmpty(strWhere) ? "1=1" : strWhere);

            try
            {
                dst = db.ExecuteParamDataSet(strSql, values);
            }
            catch (Exception ex)
            {
                this.message = ex.Message;
            }
            return dst;
        }
        /// <summary>
        /// 判断是否重复
        /// </summary>
        /// <param name="mTableName"></param>
        /// <param name="primaryKey"></param>
        /// <param name="primaryValue"></param>
        /// <param name="key"></param>
        /// <param name="keyValue"></param>
        /// <returns></returns>
        public bool IsRepeat(TableInfo mTableName, object primaryValue, string key, object keyValue)
        {
            bool flag = false;

            StringBuilder sqlExist = new StringBuilder();

            sqlExist.AppendFormat(@"SELECT count({0}) FROM {1} WHERE {0}='{2}' AND {3} NOT IN ('{4}') ", key, mTableName.TableName, keyValue, mTableName.PrimaryName, primaryValue);

            try
            {
                flag = Convert.ToBoolean(db.ExecuteParamScalar(sqlExist.ToString()));
            }
            catch (Exception ex)
            {
                this.message = ex.Message;
            }

            return flag;

        }
        /// <summary>
        /// 获取fieldName字段的单个数据
        /// </summary>
        /// <param name="mTableName">表或视图名的枚举</param>
        /// <param name="strWhere">带参数的条件语句</param>
        /// <param name="values">参数一一对应值</param>
        /// <returns></returns>
        public object GetParamScalar(TableInfo eTableName, string fieldName, string strWhere, params object[] values)
        {
            object res = null;

            string strSql = string.Format("select {1} from {0} where {2}", eTableName.TableName, fieldName, strWhere == null || strWhere.Length == 0 ? "1=1" : strWhere);

            try
            {
                res = db.ExecuteParamScalar(strSql, values);
            }
            catch (Exception ex)
            {
                this.message = ex.Message;
            }
            return res;
        }

        #region 操作数据
        /// <summary>
        /// 删除单条数据
        /// </summary>
        /// <param name="eTableName"></param>
        /// <param name="primaryName"></param>
        /// <param name="primaryValue"></param>
        /// <param name="enumErrorWarning">提示信息</param>
        /// <returns></returns>
        public bool DeleteData(TableInfo eTableName, string primaryName, string primaryValue, EnumErrorWarning enumErrorWarning)
        {
            bool flag = false;

            string strSql = string.Format("delete from {0} Where {1}=@{1}", eTableName.TableName, eTableName.PrimaryName);
            object[] pra = { primaryValue };
            try
            {
                flag = db.ExecuteParameterSql(strSql, pra);
            }
            catch (Exception ex)
            {
                this.message = ex.Message;
            }
            return flag;
        }
        /// <summary>
        /// 删除单条数据
        /// </summary>
        /// <param name="table"></param>
        /// <param name="keyName"></param>
        /// <param name="keyValue"></param>
        /// <returns></returns>
        public bool DeleteData(TableInfo eTableName, string primaryValue, EnumErrorWarning enumErrorWarning)
        {
            bool flag = false;
            string strSql = string.Format("delete from {0} Where {1}='{2}'", eTableName.TableName, eTableName.PrimaryName, primaryValue);
            try
            {
                string[] arr = null;
                flag = db.ExecuteParameterSql(strSql, arr);
            }
            catch (Exception ex)
            {
                this.message = ex.Message;
            }
            return flag;
        }
        /// <summary>
        /// 删除多条数据
        /// </summary>
        /// <param name="eTableName"></param>
        /// <param name="enumErrorWarning">提示信息</param>
        /// <param name="primaryValues"></param>
        /// <returns></returns>
        public bool DeleteDatas(TableInfo eTableName, EnumErrorWarning enumErrorWarning, params string[] primaryValues)
        {
            bool flag = false;

            StringBuilder sbWhere = new StringBuilder("");

            foreach (string primaryValue in primaryValues)
            {
                sbWhere.AppendFormat(",'{0}'", primaryValue);
            }
            if (sbWhere.Length != 0)
                sbWhere.Remove(0, 1);

            string strSql = string.Format("delete from {0} Where {1} IN ({2})", eTableName.TableName, eTableName.PrimaryName, sbWhere.ToString());

            try
            {
                flag = db.ExecuteSql(strSql) > 0;
            }
            catch (Exception ex)
            {
                this.message = ex.Message;
            }
            return flag;
        }
        /// <summary>
        /// 新增和更新单表行数据
        /// </summary>
        /// <param name="enumTableName"></param>
        /// <param name="dataFields"></param>
        /// <param name="enumErrorWarning"></param>
        /// <returns></returns>
        public bool AddUpdateData(TableInfo enumTableName, Hashtable dataFields, EnumErrorWarning enumErrorWarning)
        {
            bool flag = false;

            try
            {
                dataFields.Add("ModifyPersonAccount", "");
                dataFields.Add("ModifyPersonName", "");
                dataFields.Add("ModifyTime", System.DateTime.Now);
                flag = db.UpdateData(dataFields, enumTableName.TableName);

            }
            catch (Exception ex)
            {
                this.message = ex.Message;
            }
            return flag;
        }
        /// <summary>
        /// 新增和更新单表行数据
        /// </summary>
        /// <param name="tableName">数据表名</param>
        /// <param name="keyName">主键名</param>
        /// <param name="dataFields"></param>
        /// <param name="enumErrorWarning"></param>
        /// <returns></returns>
        public bool AddUpdateData(string tableName, string keyName, Hashtable dataFields, EnumErrorWarning enumErrorWarning)
        {
            bool flag = false;

            try
            {
                dataFields.Add("ModifyPersonAccount", "");
                dataFields.Add("ModifyPersonName", "");
                dataFields.Add("ModifyTime", System.DateTime.Now);
                flag = db.UpdateData(dataFields, tableName);
            }
            catch (Exception ex)
            {
                this.message = ex.Message;
            }
            return flag;
        }
        /// <summary>
        /// 新增和更新多表行行数据
        /// </summary>
        /// <param name="tableDataFields"></param>
        /// <returns></returns>
        public bool AddUpdateData(Dictionary<Hashtable, TableInfo> tableDataFields, EnumErrorWarning enumErrorWarning)
        {
            bool flag = false;

            try
            {
                Dictionary<Hashtable, string> tDataFields = new Dictionary<Hashtable, string>();

                foreach (System.Collections.Generic.KeyValuePair<Hashtable, TableInfo> tDataField in tableDataFields)
                {
                    tDataFields.Add(tDataField.Key, tDataField.Value.TableName);
                    //若不是要物理删除的数据，则添加修改信息
                    if (!(tDataField.Key.Count == 1 && tDataField.Key.Contains(tDataField.Value.PrimaryName)))
                    {
                        //if (!tDataField.Key.Contains("MODIFYPERSONACCOUNT")) { tDataField.Key.Add("ModifyPersonAccount", ""); }
                        //if (!tDataField.Key.Contains("MODIFYPERSONNAME")) { tDataField.Key.Add("ModifyPersonName", ""); }
                        //if (!tDataField.Key.Contains("MODIFYTIME")) { tDataField.Key.Add("ModifyTime", System.DateTime.Now); }
                    }
                }
                flag = db.UpdateData(tDataFields);
            }
            catch (Exception ex)
            {
                this.message = ex.Message;
            }
            return flag;
        }
        #endregion

        /// <summary>
        /// 执行sql语句返回更新结果
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public bool UpdateRows(string sql, EnumErrorWarning enumErrorWarning)
        {
            bool flag = false;
            try
            {
                flag = db.ExecuteParameterSql(sql);
            }
            catch (Exception ex)
            {
                this.message = ex.Message;
            }
            return flag;
        }

        #region <--预防"提交"按钮的多次点击-->
        /// <summary>
        /// 预防"提交"按钮的多次点击
        /// </summary>
        /// <param name="page">页面对象</param>
        /// <param name="button">按钮对象</param>
        public void RegisterForbidScript(System.Web.UI.Page page, System.Web.UI.WebControls.Button button)
        {
            button.Attributes.Add("onclick", string.Format("forbid{0}=true;", button.ID));
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            sb.AppendFormat("if   (!forbid{0})   return;", button.ID);
            sb.AppendFormat("var   button{0}=document.getElementById('{0}');", button.ID);
            sb.AppendFormat("button{0}.value=\"请稍等...\";", button.ID);
            sb.Append("document.body.style.cursor='wait';");
            sb.AppendFormat("button{0}.disabled=true;", button.ID);

            string strScript = "<script>";
            strScript = strScript + string.Format("var   forbid{0}=false;", button.ID);

            //灏嗗嚱鏁扮粦瀹氬埌椤甸潰鐨刼nbeforeunload浜嬩欢:     
            strScript = strScript + "window.attachEvent('onbeforeunload',function(){" + sb.ToString() + "});";
            strScript = strScript + "</" + "script>";
            page.ClientScript.RegisterStartupScript(page.GetType(), "onbeforeunload", strScript);
        }
        #endregion

        /// <summary>
        /// 新增或更新缓存单表的行数据
        /// </summary>
        /// <param name="dataFields">数据字段集</param>
        /// <param name="cacheKey">缓存Key值(需要外部维护，规定为为ViewState[tableName]对象的值,规定为tableName+分隔符号+随机的GUID值)</param>
        /// <returns></returns>
        public DataTable AddUpdateCacheData(TableInfo tableInfo, FieldData dataFields, string cacheKey)
        {
            DataTable dtb = null;

            if (System.Web.HttpContext.Current.Cache[cacheKey] == null)
            {
                // throw new ApplicationException("当新增或更新行数据时找不到键值为" + cacheKey + "缓存表数据,从数据库获取后用SetCacheData方法赋值");
                return dtb;
            }

            dtb = (DataTable)System.Web.HttpContext.Current.Cache[cacheKey];

            //判断新增还是修改

            DataRow row = null;
            DataRow[] rows = dtb.Select(string.Format("{0}='{1}'", tableInfo.PrimaryName, dataFields[tableInfo.PrimaryName]));
            if (rows.Length == 0)
            {
                row = dtb.NewRow();
                row["CreateTime"] = DateTime.Now;

                dtb.Rows.Add(row);
            }
            else//修改
            {
                row = rows[0];
                row["ModifyTime"] = DateTime.Now;

            }
            foreach (DictionaryEntry de in dataFields)
            {
                row[de.Key.ToString()] = de.Value == null || de.Value.ToString().Length == 0 ? Convert.DBNull : de.Value;
            }

            row[bColumnName] = (int)EnumCacheState.Current;//有效保存数据

            return dtb;
        }
        /// <summary>
        /// 从缓存中读取数据保存到子表
        /// </summary>
        /// <param name="subTableName"></param>
        /// <returns></returns>
        public Dictionary<Hashtable, TableInfo> GetCacheDatas(string cacheKey, TableInfo mTableName)
        {
            //用于存放表中的所有行数据
            Dictionary<Hashtable, TableInfo> tableDataFields = new Dictionary<Hashtable, TableInfo>();
            try
            {
                string primaryField = mTableName.PrimaryName;
                DataTable subTable = (DataTable)System.Web.HttpContext.Current.Cache[cacheKey];
                if (subTable == null)
                {
                    return tableDataFields;
                }
                //复制子表架构，且移出保存判断有效列,用于下面的有效列
                DataTable subTableClone = subTable.Clone();
                subTableClone.Columns.Remove(bColumnName);
                //处理最终数据
                foreach (DataRow row in subTable.Rows)
                { //保存子表数据集
                    Hashtable subDataFields = new Hashtable();
                    //Deleted
                    if ((int)row[bColumnName] == (int)EnumCacheState.Deleted)
                    {//当数据只存储主键时,做删除操作
                        subDataFields.Add(primaryField, row[primaryField]);
                    }
                    else
                    {
                        foreach (DataColumn column in subTableClone.Columns)
                        {
                            subDataFields.Add(column.ColumnName, row[column.ColumnName]);
                        }
                    }
                    tableDataFields.Add(subDataFields, mTableName);
                }
            }
            catch (Exception ex)
            {
                this.message = ex.Message;
            }
            return tableDataFields;
        }
        /// <summary>
        /// 获取cachekey缓存数据
        /// </summary>
        /// <param name="cacheKey"></param>
        /// <returns></returns>
        public DataView GetCacheData(string cacheKey)
        {
            DataView dv = null;

            DataTable dtb = (DataTable)System.Web.HttpContext.Current.Cache[cacheKey];

            if (dtb != null)
            {
                dv = dtb.DefaultView;
                dv.RowFilter = string.Format("{0}<>{1}", bColumnName, (int)EnumCacheState.Deleted);
            }

            return dv;

        }
        /// <summary>
        /// 给label赋值时间
        /// </summary>
        /// <param name="lb"></param>
        /// <param name="date"></param>
        public void SetDateTime(Label lb, string date)
        {
            if (date != string.Empty)
            {
                lb.Text = Convert.ToDateTime(date).ToShortDateString();
            }
        }
    }
}
